//
// Created by Administrator on 2020/1/14.
//

#include <unistd.h>
#include <sys/stat.h>
#include "riru.h"
#include "log_utils.h"
#include "process_utils.h"
#include "file_utils.h"
#include "string_utils.h"
#include "module_manager.h"
#include "entry_hooks.h"

#define LOG_TAG "Riru"

static bool DEBUGGABLE=true;

void check_context(){
    int uid=getuid();
    if(uid!=0
    &&!DEBUGGABLE){
        AKTagLogErr("riru must run in a uid=0 context\n");
        return;
    }
    if(DEBUGGABLE)
        system("start adbd");//确保adb启动
    int pid=getpid();
    std::string process_name;
    get_process_name(pid,process_name);
    AKTagLog("process_name:%s\n",process_name.c_str());
}

static bool riru_init_status= false;

void init_dispatcher(std::string &module_dir) {
    if(riru_init_status){
        AKTagLogErr("Riru has been initialized\n");
        return;
    }
    check_context();
    if(module_dir.empty()) {
        AKTagLogErr("module_dir is empty,use default:%s\n",DEFAULT_MODULE_PATH);
        module_dir = DEFAULT_MODULE_PATH;
    }
    if (!get_or_create_dir(module_dir,true)) {
        AKTagLogErr("fail to access module dir:%s\n", module_dir.c_str());
        return;
    }
    std::vector<std::string> file_list;
    enum_files(module_dir, false,file_list);
    for (auto itor = file_list.begin();itor!=file_list.end() ; itor++) {
        std::string file_path=itor->c_str();
        if(!contains(file_path,".so"))
            continue;
        AKTagLog("found so:%s\n",file_path.c_str());
        Module* module=new Module(file_path);
        AKTagLog("module object:%p created\n",module);
        ModuleManager::GetInstance()->Add(module);
    }
    riru_init_status= hook_create_jvm();
    AKTagLog("Riru has finished its preparation\n");
}

class static_initializer {
public:
    static_initializer() {
        std::string module_dir=DEFAULT_MODULE_PATH;
        init_dispatcher(module_dir);
    }
};
static static_initializer s;